// Keywords: quantitative trait, negative frequency-dependence, squashed stabilizing selection

initialize() {
	defineConstant("COMP", T);	// is competition enabled?
	
	initializeMutationRate(1e-7);
	initializeMutationType("m1", 0.5, "f", 0.0);       // neutral
	initializeMutationType("m2", 0.5, "n", 0.0, 0.15);  // QTLs
	m2.convertToSubstitution = F;
	initializeGenomicElementType("g1", c(m1, m2), c(1.0, 0.1));
	initializeGenomicElement(g1, 0, 99999);
	initializeRecombinationRate(1e-8);
}
mutationEffect(m2) { return 1.0; }
1 early() {
	sim.addSubpop("p1", 500);
	cat("Phenotypes: 0");
}
1:5000 late() {
	inds = sim.subpopulations.individuals;
	phenotypes = inds.sumOfMutationsOfType(m2);
	stabilizing = dnorm(phenotypes, 5.0, 2.0) / dnorm(5.0, 5.0, 2.0);
	competition = sapply(phenotypes, "sum(dnorm(phenotypes, applyValue, 0.3));");
	competition = 1.0 - (competition / size(inds)) / dnorm(0.0, 0.0, 0.3);
	inds.fitnessScaling = 1.0 + stabilizing * (COMP ? competition else 1.0);
	
	if (sim.cycle % 10 == 0)
		cat(", " + mean(phenotypes));
	
	if (exists("slimgui"))
	{
		// plot the relative densities
		x1 = -2; x2 = 12; step = 0.5;
		centers = seq(from=x1, to=x2 + step*0.01, by=step);
		breaks = seq(from=x1 - step/2, to=x2 + step*0.51, by=step);
		intervals = findInterval(phenotypes, breaks, allInside=T);
		counts = tabulate(intervals, length(centers) - 1);
		density = counts / max(counts);
		
		plot_pheno = slimgui.createPlot("Phenotypic Distribution",
			xrange=c(-0.5, 10.5), yrange=c(-0.05, 1.05),
			xlab="Phenotypic trait value", ylab="Relative density",
			width=500, height=250);
		plot_pheno.axis(1, at=c(0,5,10));
		plot_pheno.abline(v=5.0, color="cornflowerblue", lwd=2);
		plot_pheno.lines(centers, density, lwd=2);
		
		// plot the fitness function
		pheno_vals = seq(-2, 12, by=0.1);
		stabilizing = dnorm(pheno_vals, 5.0, 2.0) / dnorm(5.0, 5.0, 2.0);
		competition = sapply(pheno_vals, "sum(dnorm(phenotypes, applyValue, 0.3));");
		competition = 1.0 - (competition / size(inds)) / dnorm(0.0, 0.0, 0.3);
		fitness = 1.0 + stabilizing * (COMP ? competition else 1.0);
		
		plot_fit = slimgui.createPlot("Fitness Function",
			xrange=c(-0.5, 10.5), yrange=c(0.95, 2.05),
			xlab="Phenotypic trait value", ylab="Fitness",
			width=500, height=250);
		plot_fit.axis(1, at=c(0,5,10));
		plot_fit.abline(v=5.0, color="cornflowerblue", lwd=2);
		plot_fit.lines(pheno_vals, fitness, lwd=2);
	}
}
